<?php
/**
 * GlobalConfiguration model class file.
 *
 * @package   models
 * @since     1.0
 * @filesource
 */

/**
 * This is the model class for table "{{global_configuration}}".
 * This is a DAO class which is used by GlobalConfigurationController or other controllers
 * to operate data in database or return data in a specified format.
 *
 * The followings are the available columns in table '{{global_configuration}}':
 * @property integer $id
 * @property string $key
 * @property string $title
 * @property string $description
 * @property string $type
 * @property string $value
 * @property string $lastValue
 */
class GlobalConfiguration extends CActiveRecord
{
	/**
	 * The constant string value for configuration type as string.
	 * @var string
	 */
	const TYPE_STRING = 'string';
	/**
	 * The constant string value for configuration type as boolean (yes/no or true/false).
	 * @var string
	 */
	const TYPE_BOOLEAN = 'boolean';

	/**
	 * Returns the static model of the specified AR class.
	 * @return GlobalConfiguration the static model class
	 */
	public static function model($className=__CLASS__)
	{
		return parent::model($className);
	}


	/**
	 * Find the configuration value by given key, the type of the return value is as specified 
	 * in the $type property.
	 * @param string $key the key of the configuration
	 * @return mixed the value of the configuration for the given key. 
	 * @throws CHttpException if the key is not found
	 */
	public static function getByKey($key)
	{
		$cr=new CDbCriteria();
		$cr->compare('`key`', $key, false);
		$config=self::model()->find($cr);
		if($config){
			switch ($config->type) {
				case GlobalConfiguration::TYPE_STRING:
					return $config->value;
				break;
				case GlobalConfiguration::TYPE_BOOLEAN:
					return $config->value?TRUE:FALSE;
				break;
			}
		}
		throw new CHttpException(500);
	}

	/**
	 * Returns the table name.
	 * @return string the associated database table name
	 */
	public function tableName()
	{
		return '{{global_configuration}}';
	}

	/**
	 * Returns the validation rules.
	 * The rules will be used when requesting validation by call self.validate().
	 * Many class method will call self.validate(), eg: CActiveRecord.save().
	 * @return array validation rules for model attributes. 
	 */
	public function rules()
	{
		// NOTE: you should only define rules for those attributes that
		// will receive user inputs.
		return array(
			array('value', 'required','on'=>'update'),
			array('value', 'checkFolder','on'=>'update'),
			array('title', 'safe','on'=>'search'),
		);
	}

	/**
	 * Returns the labels for each column variables. 
	 * This will be used to render label on page.
	 * @return array customized attribute labels (name=>label)
	 */
	public function attributeLabels()
	{
		return array(
			'id' => 'ID',
			'key' => 'Key',
			'title' => 'Title',
			'description' => 'Description',
			'type' => 'Type',
			'value' => 'Value',
			'lastValue' => 'Last Value',
		);
	}

	/**
	 * Retrieves a list of models based on the current search/filter conditions 
	 * declared in this function.
	 * @return CActiveDataProvider the data provider that can return the models 
	 * based on the search/filter conditions.
	 */
	public function search()
	{
		$criteria=new CDbCriteria;
		
		$criteria->compare('title',$this->title,true);
		
		return new CActiveDataProvider(get_class($this), array(
			'criteria'=>$criteria,
		));
	}
	
	/**
	 * Get the readable string of value of a global configuraton setting.
	 * The values of all global configuration settings are different, including
	 * string, boolean, etc. This function will return readable string for various
	 * kinds of global configuration settings.
	 * @param boolean $lastValue
	 * @return string
	 */
	public function getReadableValue($lastValue = FALSE){
		$value=$lastValue?$this->lastValue:$this->value;
		switch ($this->type){
			case GlobalConfiguration::TYPE_STRING:
				return $value;
			case GlobalConfiguration::TYPE_BOOLEAN:
				return $value ? "YES":"NO";
		}
	}
	
	/**
	 * Validation function to check if the give path is a validate folder when
	 * setting upload root folder in system.
	 * The "UPLOAD_ROOT_FOLDER" configuration should be validated that the 
	 * folder exists on the disk.
	 * @param string $attribute
	 * @param mixed $params
	 */
	public function checkFolder($attribute,$params) {
		if ($this->key == 'UPLOAD_ROOT_FOLDER' && !is_dir($this->value)) {
			 $this->addError('value','The new folder does not exist.');
		}
	}
}